package com.example.kotlinstudy.s3

import org.junit.Test

class Test3_匿名函数_lamdel {
    @Test   //匿名函数  就叫做 lambda
    fun test() {
        val total = "Mississippi".count()
        println(total)

        val totalS = "Mississippi".count { letter -> letter == 's' }
        println(totalS)

        //变量的类型是一个匿名函数
        val blessingFunction: () -> String  //{} 直接写
        blessingFunction = {  //也可以这样写
            val h = "New Year"
            "Happy $h"   //匿名函数不用return,会直接返回最后一行  -->隐式返回
        }
        println(blessingFunction()) //不加（）是方法，加了是输出的结果

//
        val blessingFunction1: (String) -> String = { name ->
            val h = "New Year"
            "$name Happy $h"
        }


        //如果没有参数还可以简写成这样
//        val blessingFunction1 = {
//            val h = "New Year"
//            "Happy $h"
//        }

        /*
        val blessingFunction2: (String) -> String = {
            val h = "New Year"
            "$it Happy $h" //只有一个参数，还可以使用it
        }
        */

        println(blessingFunction1("lzj"))
/*   类型推断，不需要写反回类型了
        val blessingFunction2: () -> String = {
            val h = "New Year"
            "Happy $h" //只有一个参数，还可以使用it
        }
*/

        //进一步简写 类型推断-传入参数类型推断
        val blessingFunction2 = { age: Int, name: String ->
            val h = "New Year"
            "$name Happy $h $age" //只有一个参数，还可以使用it
        }
        println(blessingFunction2(10, "lzj"))

    }

    @Test  //参数是匿名函数
    fun test2() {
//        val getWordsCount = { name: String, hour: Int ->
//            val currentYear = 2027
//            "${currentYear}年 $name $hour"
//        }
//        showOnBoard("纸",getWordsCount)

        //如果lambda是唯一的参数或者排在最后，可以直接省略了 （）
        showOnBoard("纸") { name: String, hour: Int ->
            val currentYear = 2027
            "${currentYear}年 $name $hour"
        }
    }

    //具名函数
    fun showOnBoard(name: String, getWordsCount: (String, Int) -> String) {
        val hour = (1..24).shuffled().last() //随机数 ：1到24乱顺后，取最后一个
        println(getWordsCount(name, hour))
    }

    @Test //函数返回另外一个函数
    fun test3() {
        val getDiscountWords = configDiscountWords()
        println(getDiscountWords("沐浴露"))
    }


    //Kotlin lambda就是闭包  Kotlin也可以做为脚本语言，他不仅是可以是类，也可以是一个文件，当是一个文件的时候，同名就麻烦了，作用域才。。。
    fun configDiscountWords(): (String) -> String {
        val currentYear = 2027
        val hour = (1..24).shuffled().last()
        return { goodsName: String ->
//            val currentYear = 2027     //也可以写在上面 叫做作用域共享
//            val hour = (1..24).shuffled().last()
            "${currentYear}年 双11$goodsName 促销还剩 $hour 小时"
        }
    }
}